<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .box{position: absolute;left:-300px;top:400px;width: 300px;height: 50px;}
    .box .xbox{width: 300px;height: 50px;background: #ccc;}
    .box .ybox{position: absolute;width: 300px;height: 0px;background: #aaa;top: 0px;overflow: hidden;}
    .box span{width: 20px;height: 50px;background: #666;position: absolute;text-align: center;line-height: 50px;color: #fff;right: -20px;}
    .box .ybox .close{float: right;}
  </style>
</head>
<body>
  <div class="box">
    <span> > </span>
    <div class="xbox">这是横向菜单这是横向菜单这是横向菜单这是横向菜单这是横向菜单</div>
    <div class="ybox">
      <input type="button" value="x" class="close">
      这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单这是竖向菜单
    </div>
  </div>
</body>
<script>

  const box = document.querySelector(".box");
  const ybox = document.querySelector(".box .ybox");
  const span = document.querySelector('.box span');
  const close = document.querySelector('.box .ybox .close');

  span.onclick = function(){
    move(box, {left:0}, ()=>{
      move(ybox, {top: -300, height: 300});
    })
  }

  close.onclick = function(){
    move(ybox, {top: 0, height: 0}, ()=>{
      move(box, {left: -300});
    })
  }



function move(ele, obj, cb){
  if(ele.t) return;
  ele.t = setInterval(()=>{
    let state = true;
    for(let key in obj){
      let now = parseInt(getStyle(ele, key));
      let speed = (obj[key] - now) / 10;
      speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
      ele.style[key] = now + speed + "px";
      if(now !== obj[key]) state = false;
    }
    if(state){
      clearInterval(ele.t);
      ele.t = undefined;
      cb && cb();
    }
  }, 30);
}
function getStyle(ele, attr){
  if(ele.currentStyle){
    return ele.currentStyle[attr];
  }else{
    return getComputedStyle(ele)[attr];
  }
}
  
</script>
</html>